package gr.atc.epart.googlewrapper.picassaweb;

import java.io.IOException;
import java.io.StringReader;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import gr.atc.epart.HttpConnector;
import gr.atc.epart.googlewrapper.GoogleServiceCallbackType;
import gr.atc.epart.googlewrapper.accounts.GoogleAccountManager;
import gr.atc.epart.googlewrapper.youtube.YouTubeVideoEntry;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public class PicassaWeb
{
	 private GoogleAccountManager	_manager; 
	 private Activity 				_activity;
	 private Handler 				_ownerCallback;
	 private String  				_authToken;

	 //
	 // used to receive callbacks from low level asynchronous operations  
	 //
	 private Handler _messageHandler = new Handler() 
	  {
	      public void handleMessage(Message msg) 
	      {  
	          switch(msg.what) 
	          {
	        	  
	        	  case GoogleServiceCallbackType.AuthTokenReceived:
	        		  
	        		  _authToken = msg.getData().getString("AUTHTOKEN");
	        		  _ownerCallback.sendEmptyMessage(GoogleServiceCallbackType.PicassaWebServiceIsReady);
	        		  
	        		  break;
	        		  
	        	  case GoogleServiceCallbackType.UserAuthenticationRequired:
	        		  _ownerCallback.sendEmptyMessage(GoogleServiceCallbackType.UserAuthenticationRequired);
	        		  
	        		  break;

	        	  case GoogleServiceCallbackType.PicassaWebAlbumsReceived:
	        		  
	        		  String albumsFeed = msg.getData().getString("RESPONSE");
	        		  
	        		  
	        		  ArrayList<PicassaWebAlbum> albums=null;
	        		  try
	        		  {
	        			  StringReader albumsFeedReader = new StringReader(albumsFeed); 
	        			  albumsFeedReader.reset();
	        			  albums = parsePicassaWebAlbumFeed(albumsFeedReader);

	        		  }
	        		  catch (IOException e)
	        		  {
	        			  // TODO Auto-generated catch block
	        			  e.printStackTrace();
	        		  }
	        		   /*
	        		  // notify the caller that the results are ready
	        		  // and send him a list of the videos!
	        		  {
	        			  Message videoFeedsMessage = new Message();
	        			  videoFeedsMessage.what = GoogleServiceCallbackType.YouTubeVideoFeedsReceived;

	        			  Bundle bundle = new Bundle();
	        			  bundle.putSerializable("VIDEOS", videos);

	        			  videoFeedsMessage.setData(bundle);
	        			  _ownerCallback.sendMessage(videoFeedsMessage);
	        		  }
	        		  */
	        		  break;
	        		  
	        	  case GoogleServiceCallbackType.OperationError:
	        		  _ownerCallback.sendMessage(msg);
	        		  break;
	          }
	      }

		
	  };
	 
	  public PicassaWeb(Activity activity,Handler ownerCallback)
      {
			    _activity = activity;
			 	_ownerCallback = ownerCallback;
			 	
			    _manager = new GoogleAccountManager(_activity,_messageHandler);
	  }
	  
	  public void authenticate()
	  {
			    _manager.getPicassaToken();
	  }
	  
	  public void getAlbums()
		 {
			  
			 try
			 {
				HttpConnector connector = new HttpConnector();

				String searchUrl = "http://picasaweb.google.com/data/feed/api/user/default";
				
				Header[] headers = new Header[2];
				headers[0] = new BasicHeader("Authorization", "GoogleLogin auth="+_authToken);
				headers[1] = new BasicHeader("GData-Version", "2");

				connector.executeGetRequestAsync(searchUrl, GoogleServiceCallbackType.PicassaWebAlbumsReceived,_messageHandler,headers);
			 }
			 catch (Exception e)
			 {
				 
			 }
			 
		}
	  
	  public void getAlbums(String userName)
	  {
		  
	  }
	  
	  public void getAlbumPhotos(String album)
	  {
		  
	  }

	  public void getAlbumPhotos(String album,String user)
	  {
		  
	  }
	  
	  public void getPhotosAroundLocation()
	  {
		  // search geolocated photos
	  }
	  
	  public void search()
	  {
		  // search with keywords
	  }
	  
	  public void uploadPhoto()
	  {
		  // upload a phot in user's album
	  }

	  public void getPhoto(String photoUrl)
	  {
		  
	  }
	  
	  private ArrayList<PicassaWebAlbum> parsePicassaWebAlbumFeed(StringReader albumsFeed)
	  {
		   ArrayList<PicassaWebAlbum> albums = new ArrayList<PicassaWebAlbum>();
		  
		   try
		   {
				SAXReader reader = new SAXReader();
				Document feedsDocument = reader.read(albumsFeed);
				
				Element rootFeed = (Element) feedsDocument.selectSingleNode ("/feed");

				
				// get the namespaces for later Xpath 
				String rootXmlNsURI =  rootFeed.getNamespaceURI();
				String gphotoNameSpace = rootFeed.getNamespaceForPrefix("gphoto").getURI();
				String mediaNameSpace = rootFeed.getNamespaceForPrefix("media").getURI();
				String openSearchNameSpace = rootFeed.getNamespaceForPrefix("openSearch").getURI();
				String georssNameSpace = rootFeed.getNamespaceForPrefix("georss").getURI();
				String gmlNameSpace = rootFeed.getNamespaceForPrefix("gml").getURI();
				
				//String openSearchNameSpace = rootFeed.getNamespaceForPrefix("openSearch").getURI();
				
				feedsDocument.getRootElement().add(DocumentHelper.createNamespace("ns",rootXmlNsURI));
				feedsDocument.getRootElement().add(DocumentHelper.createNamespace("gphoto",gphotoNameSpace));
				feedsDocument.getRootElement().add(DocumentHelper.createNamespace("media",mediaNameSpace));
				feedsDocument.getRootElement().add(DocumentHelper.createNamespace("opensearch",openSearchNameSpace));
				feedsDocument.getRootElement().add(DocumentHelper.createNamespace("georss",georssNameSpace));
				feedsDocument.getRootElement().add(DocumentHelper.createNamespace("gml",gmlNameSpace));
				
				String searchTitle = rootFeed.elementText("title");
				String totalResults = rootFeed.selectSingleNode("opensearch:totalResults").getStringValue();
				String startIndex = rootFeed.selectSingleNode("opensearch:startIndex").getStringValue();
				String itemsPerPage = rootFeed.selectSingleNode("opensearch:itemsPerPage").getStringValue();
				
				
				List<Element> feedNodes = feedsDocument.selectNodes("//ns:feed/ns:entry");
				for (Element feed:feedNodes)
				{
					try
					{
						albums.add(parseAlbum(feed));
					}
					catch (NullPointerException e)
					{
						// ignore errors...and put as many videos as possible
					}
				}
				
			} catch (DocumentException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			return albums;
	  }

	private PicassaWebAlbum parseAlbum(Element albumEntry) throws NullPointerException
	{
		PicassaWebAlbum album = new PicassaWebAlbum();
		
		String albumId = ((Element)albumEntry.selectSingleNode("gphoto:id")).getStringValue();//  albumEntry.elementText("gphoto:id");
		album.setAlbumId(albumId);

		String title = ((Element)albumEntry.selectSingleNode("media:group/media:title")).getStringValue();
		album.setTitle(title);

   	    String description= ((Element)albumEntry.selectSingleNode("media:group/media:description")).getStringValue();
		album.setDescription(description);

		String author = ((Element)albumEntry.selectSingleNode("gphoto:user")).getStringValue();//albumEntry.elementText("gphoto:user");
		album.setAuthor(author);

		String publishDate = albumEntry.elementText("published");
		album.setPublishDate(publishDate);

		String updateDate = albumEntry.elementText("updated");
		album.setUpdateDate(updateDate);

		int numOfPhotos = Integer.parseInt(((Element)albumEntry.selectSingleNode("gphoto:numphotos")).getStringValue());
		album.setNumOfPhotos(numOfPhotos);
		
		String thumbnailurl = ((Element)albumEntry.selectSingleNode("media:group/media:thumbnail")).attributeValue("url");
		//int width = Integer.parseInt(((Element)albumEntry.selectSingleNode("media:group/media:description")).attributeValue("width"));
		//int height = Integer.parseInt(((Element)albumEntry.selectSingleNode("media:group/media:description")).attributeValue("height"));
		album.setThumbnailUrl(thumbnailurl);
		
		String[] keywords = ((Element)albumEntry.selectSingleNode("media:group/media:keywords")).getStringValue().split(",");
		album.setKeywords(keywords);

		String[] geoLocation= ((Element)albumEntry.selectSingleNode("georss:where/gml:Point/gml:pos")).getStringValue().split(" ");
		double positionLatitude = Double.parseDouble(geoLocation[0]);
		album.setGeoPositionLatitude(positionLatitude);
		
		double positionLongitute = Double.parseDouble(geoLocation[1]);
		album.setGeoPositionLongitute(positionLongitute);

		
		// TODO Auto-generated method stub
		return album;
	}
}
